home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / gnu / mtools.lha / mtools-2.0.7 / mformat.c < prev    next >
C/C++ Source or Header  |  1992-09-10  |  6KB  |  249 lines

  1. /*
  2.  * Add an MSDOS filesystem to a low level formatted diskette.
  3.  *
  4.  * Emmet P. Gray            US Army, HQ III Corps & Fort Hood
  5.  * ...!uunet!uiucuxc!fthood!egray    Attn: AFZF-DE-ENV
  6.  * fthood!egray@uxc.cso.uiuc.edu    Directorate of Engineering & Housing
  7.  *                     Environmental Management Office
  8.  *                     Fort Hood, TX 76544-5057
  9.  */
  10.  
  11. #include <stdio.h>
  12. #include <ctype.h>
  13. #include "msdos.h"
  14. #include "patchlevel.h"
  15.  
  16. int fd, dir_dirty, dir_entries;
  17. long dir_chain[MAX_DIR_SECS];
  18. unsigned char *dir_buf;
  19.  
  20. main(argc, argv)
  21. int argc;
  22. char *argv[];
  23. {
  24.     extern int optind;
  25.     extern char *optarg;
  26.     extern struct device devices[];
  27.     struct bootsector boot;
  28.     int i, c, oops, tracks, heads, sectors, fat_len, dir_len, clus_size;
  29.     int tot_sectors, num_clus, fat_guess;
  30.     long time(), now, lseek();
  31.     char drive, *name, *expand();
  32.     char *strncpy(), *memset(), *memcpy();
  33.     unsigned char media, label[12], buf[MSECTOR_SIZE];
  34.     struct device *dev;
  35.     struct directory *dir, *mk_entry();
  36.     void exit(), perror();
  37.  
  38.     oops = 0;
  39.     tracks = 0;
  40.     heads = 0;
  41.     sectors = 0;
  42.     label[0] = '\0';
  43.                     /* get command line options */
  44.     while ((c = getopt(argc, argv, "t:h:s:l:")) != EOF) {
  45.         switch (c) {
  46.             case 't':
  47.                 tracks = atoi(optarg);
  48.                 break;
  49.             case 'h':
  50.                 heads = atoi(optarg);
  51.                 break;
  52.             case 's':
  53.                 sectors = atoi(optarg);
  54.                 break;
  55.             case 'l':
  56.                 sprintf((char *) label, "%-11.11s", optarg);
  57.                 break;
  58.             default:
  59.                 oops = 1;
  60.                 break;
  61.         }
  62.     }
  63.  
  64.     if (oops || (argc - optind) != 1) {
  65.         fprintf(stderr, "Mtools version %s, dated %s\n", VERSION, DATE);
  66.         fprintf(stderr, "Usage: %s [-t tracks] [-h heads] [-s sectors] [-l label] device\n", argv[0]);
  67.         exit(1);
  68.     }
  69.  
  70.     drive = argv[argc -1][0];
  71.     if (islower(drive))
  72.         drive = toupper(drive);
  73.  
  74.                     /* check out the drive letter */
  75.     dev = devices;
  76.     while (dev->drive) {
  77.         if (dev->drive == drive)
  78.             break;
  79.         dev++;
  80.     }
  81.     if (!dev->drive) {
  82.         fprintf(stderr, "Drive '%c:' not supported\n", drive);
  83.         exit(1);
  84.     }
  85.     if (dev->tracks == 0) {
  86.         fprintf(stderr, "Non-removable media is not supported\n");
  87.         exit(1);
  88.     }
  89.                     /* find the right one */
  90.     if (!dev->gioctl) {
  91.         while (dev->drive == drive) {
  92.             if ((!tracks || dev->tracks == tracks) && (!heads || dev->heads == heads) && (!sectors || dev->sectors == sectors))
  93.                 break;
  94.             dev++;
  95.         }
  96.     }
  97.     if (dev->drive != drive) {
  98.         fprintf(stderr, "%s: Paramaters not supported\n", argv[0]);
  99.         exit(1);
  100.     }
  101.                     /* open the device */
  102.     name = expand(dev->name);
  103.     if ((fd = open(name, 2 | dev->mode)) < 0) {
  104.         perror("init: open");
  105.         exit(1);
  106.     }
  107.                     /* fill in the blanks */
  108.     if (!tracks)
  109.         tracks = dev->tracks;
  110.     if (!heads)
  111.         heads = dev->heads;
  112.     if (!sectors)
  113.         sectors = dev->sectors;
  114.  
  115.                     /* set parameters, if needed */
  116.     if (dev->gioctl) {
  117.         if ((*(dev->gioctl)) (fd, tracks, heads, sectors))
  118.             exit(1);
  119.     }
  120.                     /* do a "test" read */
  121.     if (read(fd, (char *) buf, MSECTOR_SIZE) != MSECTOR_SIZE) {
  122.         fprintf(stderr, "%s: Error reading from '%s', wrong parameters?\n", argv[0], name);
  123.         exit(1);
  124.     }
  125.                     /* get the parameters */
  126.     tot_sectors = tracks * heads * sectors;
  127.     switch (tot_sectors) {
  128.         case 320:        /* 40t * 1h * 8s = 160k */
  129.             media = 0xfe;
  130.             clus_size = 1;
  131.             dir_len = 4;
  132.             fat_len = 1;
  133.             break;
  134.         case 360:        /* 40t * 1h * 9s = 180k */
  135.             media = 0xfc;
  136.             clus_size = 1;
  137.             dir_len = 4;
  138.             fat_len = 2;
  139.             break;
  140.         case 640:        /* 40t * 2h * 8s = 320k */
  141.             media = 0xff;
  142.             clus_size = 2;
  143.             dir_len = 7;
  144.             fat_len = 1;
  145.             break;
  146.         case 720:        /* 40t * 2h * 9s = 360k */
  147.             media = 0xfd;
  148.             clus_size = 2;
  149.             dir_len = 7;
  150.             fat_len = 2;
  151.             break;
  152.         case 1440:        /* 80t * 2h * 9s = 720k */
  153.             media = 0xf9;
  154.             clus_size = 2;
  155.             dir_len = 7;
  156.             fat_len = 3;
  157.             break;
  158.         case 2400:        /* 80t * 2h * 15s = 1.2m */
  159.             media = 0xf9;
  160.             clus_size = 1;
  161.             dir_len = 14;
  162.             fat_len = 7;
  163.             break;
  164.         case 2880:        /* 80t * 2h * 18s = 1.44m */
  165.             media = 0xf0;
  166.             clus_size = 1;
  167.             dir_len = 14;
  168.             fat_len = 9;
  169.             break;
  170.         default:        /* a non-standard format */
  171.             media = 0xf0;
  172.             if (heads == 1)
  173.                 clus_size = 1;
  174.             else
  175.                 clus_size = (tot_sectors > 2000) ? 1 : 2;
  176.             if (heads == 1)
  177.                 dir_len = 4;
  178.             else
  179.                 dir_len = (tot_sectors > 2000) ? 14 : 7;
  180.             /*
  181.              * Estimate the fat length, then figure it out.  The
  182.              * 341 is the number of 12 bit fat entries in a sector.
  183.              */
  184.             fat_guess = ((tot_sectors / clus_size) / 341.0) + 0.95;
  185.             num_clus = (tot_sectors -dir_len - (2 * fat_guess) -1) / clus_size;
  186.             fat_len = (num_clus / 341.0) + 1;
  187.             break;
  188.     }
  189.                     /* the boot sector */
  190.     memset((char *) &boot, '\0', MSECTOR_SIZE);
  191.     boot.jump[0] = 0xeb;
  192.     boot.jump[1] = 0x44;
  193.     boot.jump[2] = 0x90;
  194.     strncpy((char *) boot.banner, "Mtools  ", 8);
  195.     boot.secsiz[0] = 512 % 0x100;
  196.     boot.secsiz[1] = 512 / 0x100;
  197.     boot.clsiz = (unsigned char) clus_size;
  198.     boot.nrsvsect[0] = 1;
  199.     boot.nrsvsect[1] = 0;
  200.     boot.nfat = 2;
  201.     boot.dirents[0] = (dir_len * 16) % 0x100;
  202.     boot.dirents[1] = (dir_len * 16) / 0x100;
  203.     boot.psect[0] = tot_sectors % 0x100;
  204.     boot.psect[1] = tot_sectors / 0x100;
  205.     boot.descr = media;
  206.     boot.fatlen[0] = fat_len % 0x100;
  207.     boot.fatlen[1] = fat_len / 0x100;
  208.     boot.nsect[0] = sectors % 0x100;
  209.     boot.nsect[1] = sectors / 0x100;
  210.     boot.nheads[0] = heads % 0x100;
  211.     boot.nheads[1] = heads / 0x100;
  212.  
  213.                     /* write the boot */
  214.     lseek(fd, 0L, 0);
  215.     write(fd, (char *) &boot, MSECTOR_SIZE);
  216.                     /* first fat */
  217.     memset((char *) buf, '\0', MSECTOR_SIZE);
  218.     buf[0] = media;
  219.     buf[1] = 0xff;
  220.     buf[2] = 0xff;
  221.     write(fd, (char *) buf, MSECTOR_SIZE);
  222.     memset((char *) buf, '\0', MSECTOR_SIZE);
  223.     for (i = 1; i < fat_len; i++)
  224.         write(fd, (char *) buf, MSECTOR_SIZE);
  225.                     /* second fat */
  226.     buf[0] = media;
  227.     buf[1] = 0xff;
  228.     buf[2] = 0xff;
  229.     write(fd, (char *) buf, MSECTOR_SIZE);
  230.     memset((char *) buf, '\0', MSECTOR_SIZE);
  231.     for (i = 1; i < fat_len; i++)
  232.         write(fd, (char *) buf, MSECTOR_SIZE);
  233.                     /* the root directory */
  234.     if (label[0] != '\0') {
  235.         time(&now);
  236.         dir = mk_entry(label, 0x08, 0, 0L, now);
  237.         memcpy((char *) buf, (char *) dir, MDIR_SIZE);
  238.     }
  239.     write(fd, (char *) buf, MSECTOR_SIZE);
  240.     memset((char *) buf, '\0', MSECTOR_SIZE);
  241.     for (i = 1; i < dir_len; i++)
  242.         write(fd, (char *) buf, MSECTOR_SIZE);
  243.     close(fd);
  244.     exit(0);
  245. }
  246.  
  247. /* hooks for the missing parts */
  248. void disk_write() {}
  249.